package org.six11.olive3.picturephone.server;

import java.io.File;
import java.util.HashMap;

import javax.naming.NamingException;
import org.six11.olive3.net.MessageNames;
import org.six11.olive3.picturephone.server.handler.*;
import org.six11.olive3.server.DownloadMessageHandler;
import org.six11.olive3.server.InkBroker;
import org.six11.olive3.util.MultiState;
import org.six11.util2.Debug;

/**
 * A Picturephone Servlet for handling game events. These events include:
 * 
 * 1. Descriptions:
 * 
 * 1a. User requests a description they haven't been involved with. Server replies with a
 * description id and text.
 * 
 * 1b. User uploads a sketch for description_id. Server stores it and does not respond.
 * 
 * 2. Sketches:
 * 
 * 2a. User requests a sketch they haven't been involved with. Server replies with the message log
 * constituting the sketch, and gives the sketch id.
 * 
 * 2b. User is adding more sketch data to an ongoing sketch. Client supplies some sketch messages.
 * Server simply adds it to an ongoing cache and doesn't really reply.
 * 
 * 2c. User says 'I am done with this sketch' and supplies the associated description id. Server
 * stores the ongoing sketch and disallows further input.
 * 
 * 3. Judgements:
 * 
 * 3a. User requests a judgement they haven't been involved with. Server responds with two separate
 * sketches. This will require adding a delimiter in the text message stream to separate the two.
 * 
 * 3b. User issues a judgement. Server stores the judgement and replies true if successful.
 * 
 * @author Gabe Johnson <johnsogg@cmu.edu>
 */
public class PPServer extends InkBroker {
  public PPServer() throws NamingException {
    super();
    Debug.useTime = true;

    // this object links to all shared information such as message queues.
    MultiState programState = new MultiState();
    programState.setValue(ServerStateConstants.MESSAGE_QUEUES, new HashMap<String, MessageQueue>());

    // Ensure pen messages are added to a sketch data cache
    MessageCacheHandler sketchHandler = new MessageCacheHandler();
    handler.registerAsynchronousHandler(MessageNames.MSG_PEN, sketchHandler);

    ScoreHandler scoreHandler = new ScoreHandler(dbThing, programState);
    programState.setValue(ServerStateConstants.HANDLER_SCORE, scoreHandler);
    RateRequestMessageHandler rateReqHandler = new RateRequestMessageHandler(dbThing);
    SketchRequestMessageHandler sketchReqHandler = new SketchRequestMessageHandler(dbThing);
    DescriptionRequestMessageHandler descReqHandler = new DescriptionRequestMessageHandler(dbThing);

    // Clients send a download request periodically. Messages we want to give to them are in a queue
    // which is accessed via this. The 'data' variable is a protected member of InkBroker.
    handler.registerSynchronousHandler(MessageNames.MSG_REQUEST_DOWNLOAD,
        new DownloadMessageHandler(data, programState));

    handler.registerSynchronousHandler(PPMessageNames.MSG_DESC_REQ, descReqHandler);

    handler.registerAsynchronousHandler(PPMessageNames.MSG_SKETCH_DONE,
        new SketchDoneMessageHandler(dbThing, programState, sketchHandler));

//    handler.registerSynchronousHandler(PPMessageNames.MSG_SKETCH_REQ, sketchReqHandler);

    handler.registerAsynchronousHandler(PPMessageNames.MSG_DESC_DONE,
        new DescriptionDoneMessageHandler(dbThing, programState));

//    handler.registerSynchronousHandler(PPMessageNames.MSG_RATE_REQ, rateReqHandler);

    handler.registerAsynchronousHandler(PPMessageNames.MSG_RATE_DONE, new RateDoneMessageHandler(
        dbThing, programState));

    handler.registerSynchronousHandler(PPMessageNames.MSG_SCORE_REQ, scoreHandler);

    handler.registerSynchronousHandler(PPMessageNames.MSG_ANYTHING_REQ, new AnythingRequestHandler(
        rateReqHandler, sketchReqHandler, descReqHandler, dbThing));

    handler.registerAsynchronousHandler(PPMessageNames.MSG_INIT, new InitMessageHandler(dbThing,
        programState, scoreHandler));
  }

  private void bug(String what) {
    Debug.out("PPServer", what);
  }
}
